﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using DTC.Models;
using System.Threading;

namespace Common
{

    public class AtrParser : DataPaser, IDataPaser
    {

        #region 字段定义

        private static List<string> colunms = new List<string>();
        public List<TestSpan> Spans = new List<TestSpan>();
        #endregion
        #region 构造函数
        public AtrParser(string fileName)
            : base(fileName)
        {
        }
        #endregion
        #region 获取数据列的标题
        /// <summary>
        /// 获取列的名字
        /// </summary>
        /// <returns></returns>
        public List<string> getCorlumnNames()
        {
            List<string> corList = new List<string>();
            string tilestring = getCurrentTitleString();
            StringReader sr = new StringReader(tilestring);
            string line1 = sr.ReadLine();
            string line2 = sr.ReadLine();
            #region 将两行标题数据解析，并整合到一个list中
            string partern = "\"(.*?)\"";
            var items1 = Regex.Matches(line1, partern);
            var items2 = Regex.Matches(line2, partern);
            if (items1.Count != items2.Count)
            {
                throw new Exception(string.Format("获取标题是两行的列数不一致!" + System.Environment.NewLine
                    + "line1: " + line1 + Environment.NewLine
                    + "line2: " + line2));
            }
            //缓存主标题

            string colunmTemp = "";
            string value1tmp = "";//将重名测试项重命名
            int temInt = 0;
            for (int i = 0; i < items1.Count; i++)
            {
                string strCorlunmName = "";
                string value1 = items1[i].Groups[1].Value.ToString();
                string value2 = items2[i].Groups[1].Value.ToString();
                if (string.IsNullOrEmpty(value1) && string.IsNullOrEmpty(value2))
                {
                    if (colunmTemp.Contains("Pass/Fail"))
                    {
                        value1 = "NOP";
                    }
                    else
                    {
                        value1 = colunmTemp;
                        value2 = "Result";
                    }
                }
                else if (string.IsNullOrEmpty(value1))
                {
                    value1 = colunmTemp;
                }
                else
                {
                    #region 当主标题以0开头时，去掉前面的数字和空格
                    if (value1.Contains("0"))
                    {
                        string pattern = @"^\d{1,3}\s*(\w*)";
                        Match m = Regex.Match(value1, pattern);
                        if (m.Groups[1].Value != value1tmp)
                        {
                            temInt = 0;
                            value1tmp = m.Groups[1].Value;
                            value1 = "*" + m.Groups[1].Value + "-";
                        }
                        else
                        {
                            value1 = "*" + m.Groups[1].Value+(++temInt).ToString() + "-";
                        }
                        
                        if (value1.Contains("CTY"))
                        {
                            value2 = "Result";
                        }
                    }
                    #endregion
                    colunmTemp = value1;   //对列头进行赋值
                }
                strCorlunmName = value1 + value2;
                corList.Add(strCorlunmName);
            }
            #endregion
            colunms = corList;
            return corList;
        }
        #endregion
        #region 获取文件中最后一个包含“Result #”的字串
        /// <summary>
        /// 获取文件中最后一个包含“Result #”的字串
        /// </summary>
        /// <returns>最后一个包含Result #的字串</returns>
        private string getCurrentTitleString()
        {
            List<string> titles = new List<string>();
            FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            using (StreamReader sr = new StreamReader(fs))
            {
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    if (line.Contains("Result #"))
                    {
                        line += Environment.NewLine + sr.ReadLine();
                        titles.Add(line);
                    }
                }
            }
            return titles[titles.Count - 1];
        }
        #endregion
        #region 获取最后一列的数据

        /// <summary>
        /// 获取最后一列的数据
        /// </summary>
        /// <returns></returns>
        public List<string> getLastRecord()
        {
            if (colunms == null || colunms.Count <= 0)
            {
                colunms = getCorlumnNames();
            }
            List<string> record = new List<string>();
            string line = ReadLastLine(FileName, 1, Encoding.Default);
            line = line.TrimEnd(new char[] { ',', '\r', '\n', '"' });
            if (line.Contains("Result #") || line.Contains("Minimum"))
            {
                colunms = getCorlumnNames();
                return null;
            }
            string[] values = line.Split(new char[1] { ',' });
            foreach (string value in values)
            {
                record.Add(value.Trim(new char[1] { '"' }));
            }
            if (record.Count != colunms.Count)
            {
                throw new Exception("数据数目和列数不一致");
            }
            return record;
        }
        #endregion
        private List<atrSection> getTestItems()
        {
            if (colunms == null || colunms.Count <= 0)
            {
                colunms = getCorlumnNames();
            }
            List<atrSection> sections = new List<atrSection>();
            for (int i = 0; i < colunms.Count; )
            {
                string strCor = colunms[i];
                if (strCor.Contains("*"))
                {
                    strCor = strCor.Trim('*');
                    string[] Values = strCor.Split('-');
                    string Item = Values[0];
                    atrSection sec = new atrSection();
                    sec.Name = Item;
                    for (int j = i; ; j++)
                    {
                        string keyword = "*" + Item + "-";
                        string corName = colunms[j];
                        if (corName.Contains(keyword))
                        {

                            atrItem ai = new atrItem();
                            ai.Name = colunms[j].Split('-')[1];
                            ai.Location = j;
                            sec.listItem.Add(ai);
                            if (ai.Name == "Result")
                            {
                                i = j;
                                break;
                            }
                        }
                        else
                        {
                            i = j;
                            break;
                        }
                    }
                    if (!(sec.listItem[0].Name == "Polarity"))
                    {
                        sections.Add(sec);
                    }
                }
                i++;
            }
            
            return sections;
        }
        public bool getTestSpans(ref List<TestSpan> spans)
        {
            if (colunms == null || colunms.Count <= 0)
            {
                colunms = getCorlumnNames();
            }
            List<atrSection> sections = getTestItems();
            bool result = true;
            for (int i = 0; i < sections.Count; i++)
            {
                atrSection atr = sections[i];
                TestSpan ts = new TestSpan();
                ts.测试项目 = atr.Name;
                List<string> values = getLastRecord();
                if (!getResult(atr, values))
                {
                    ts.不良数量 = (++CountManager.zcFailCount[i]).ToString();
                }
                else
                {
                    ts.不良数量 = CountManager.zcFailCount[i].ToString();
                }
                CountManager.zcTotalCount[i]++;
                string value;
                value = getSpecValue("MINIMUM", atr, values);
                if (value == "")
                {
                    ts.最小值 = "NA";
                }
                else
                {
                    ts.最小值 = value;
                }
                value = getSpecValue("MAXIMUM", atr, values);
                if (value == "")
                {
                    ts.最大值 = "NA";
                }
                else
                {
                    ts.最大值 = value;
                }
                value = getSpecValue("READING", atr, values);
                if (value == "")
                {
                    ts.测试值 = getSpecValue("RESULT", atr, values).Trim('*').ToUpper();
                }
                else
                {
                    ts.测试值 =value;
                }
                ts.不良率 = ((CountManager.zcFailCount[i] * 1.0) / (CountManager.zcTotalCount[i] > 0 ? CountManager.zcTotalCount[i] : 1)).ToString("P");
                ts.测试结果  = getSpecValue("RESULT", atr, values).Trim('*').ToUpper();
                if (ts.测试结果.Contains("FAIL"))
                {
                    result = false;
                }
                spans.Add(ts);
            }
            return result;
        }

        private static bool getResult(atrSection atr, List<string> values)
        {
            foreach (atrItem ar in atr.listItem)
            {
                if (ar.Name.ToUpper().Contains("RESULT"))
                {
                    if (values[ar.Location].ToUpper().Contains("PASS"))
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                    
                }
            }
            return false;
        }

        private static string getSpecValue(string Item, atrSection atr, List<string> values)
        {
            foreach (atrItem ar in atr.listItem)
            {
                string IteName = ar.Name.ToUpper();
                if (IteName == Item)
                {
                    return values[ar.Location];
                }
            }
            return "";
        }
        public static bool GetAtrFileName(string Path, out string FileName,DateTime dt)
        {
            string pattern=string.Format(@"C*{0}.atr", dt.ToString("ddMMyy"));
            string[] files = Directory.GetFiles(Path, pattern);
            if (files.Length > 0)
            {
                FileName = files[0];
                return true;
            }
            else
            {
                FileName = "";
                return false;
            }
        }
    }
    public class CCDParser : DataPaser, IDataPaser
    {
        public CCDParser(string fileName)
            : base(fileName)
        {
        }
        public List<string> getCorlumnNames()
        {
            List<string> slist = new List<string>();
            using (StreamReader sr = new StreamReader(FileName, Encoding.GetEncoding("gb2312")))
            {
                string line = sr.ReadLine().TrimEnd(new char[] { ',' });
                if (string.IsNullOrEmpty(line))
                    throw new Exception("没有读到标题数据");
                string[] titles = line.Split(new char[] { ',' });
                foreach (string title in titles)
                {
                    slist.Add(title);
                }
            }
            return slist;
        }
        public List<string> getLastRecord()
        {
            List<string> slist = new List<string>();
            string line = ReadLastLine(FileName, 1, Encoding.Default).TrimEnd(new char[] { '\r', '\n', ',' });
            string[] fileds = line.Split(new char[] { ',' });
            foreach (string filed in fileds)
            {
                slist.Add(filed);
            }
            return slist;
        }
        public bool getResult(ref List<TestSpan> tss,ref List<string> values)
        {
            values = getLastRecord();
            string strResult = values[values.Count - 1];
            double result =double.Parse(strResult);
            bool bret = result > 0 ? true : false;
            TestSpan ts = new TestSpan();
            if (!bret)
            {
                CountManager.txFailCount++; 
            }
            CountManager.txTotalCount++;
            ts.测试结果 = (bret ? "PASS" : "FAIL");
            ts.测试项目 = "图像";
            ts.测试值 = (bret ? "PASS" : "FAIL");
            ts.最大值 = "NA";
            ts.最小值 = "NA";
            ts.不良数量 = CountManager.txFailCount.ToString();
            ts.不良率 = (CountManager.txFailCount * 1.0 / CountManager.txTotalCount).ToString("P");
            tss.Add(ts);
            return result>0?true:false;
        }
    }

    public class LGParser : DataPaser, IDataPaser
    {
        public LGParser(string fileName)
            : base(fileName)
        {
        }
        public List<string> getCorlumnNames()
        {
            List<string> slist = new List<string>();
            using (StreamReader sr = new StreamReader(FileName, Encoding.GetEncoding("gb2312")))
            {
                string line = sr.ReadLine().TrimEnd(new char[] { ',' });
                if (string.IsNullOrEmpty(line))
                    throw new Exception("没有读到标题数据");
                string[] titles = splitLine(line);
                foreach (string title in titles)
                {
                    slist.Add(title);
                }
            }
            return slist;
        }
        public List<string> getLastRecord()
        {
            List<string> slist = new List<string>();
            string line = ReadLastLine(FileName, 1, Encoding.Default).TrimEnd(new char[] { '\r', '\n', ',' });
            string[] fileds = splitLine(line);
            foreach (string filed in fileds)
            {
                slist.Add(filed);
            }
            return slist;
        }
        private string[] splitLine(string line)
        {
            string[] fileds = line.Split(new char[] { ',', '\t' });
            return fileds;
        }
    }
    public abstract class DataPaser
    {
        public string FileName { get; set; }
        public DataPaser(string fileName)
        {
            FileName = fileName;
            if (!File.Exists(FileName))
                throw new Exception(string.Format("文件： {0} 不存在", FileName));
        }
        #region 静态方法:从后面开始读数据行
        /// <summary>
        /// 读取文本文件最后的内容
        /// </summary>
        /// <param name="AFileName">文件名</param>
        /// <param name="ALineCount">行数</param>
        /// <param name="AEncoding">字符编码</param>
        /// <returns>返回读取的内容</returns>
        public static string ReadLastLine(string AFileName, int ALineCount, Encoding AEncoding)
        {
            if (ALineCount <= 0) return string.Empty;
            if (!File.Exists(AFileName)) return string.Empty; // 文件不存在
            if (AEncoding == null) AEncoding = Encoding.Default;
            using (FileStream vFileStream = new FileStream(AFileName,
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {

                if (vFileStream.Length <= 0) return string.Empty; // 空文件
                byte[] vBuffer = new byte[0x1000]; // 缓冲区
                int vReadLength; // 读取到的大小
                int vLineCount = 0; // 读取的行数
                int vReadCount = 0; // 读取的次数
                int vScanCount = 0; // 扫描过的字符数
                long vOffset = 0; // 向后读取的位置
                do
                {
                    vOffset = vBuffer.Length * ++vReadCount;
                    int vSpace = 0; // 偏移超出的空间
                    if (vOffset >= vFileStream.Length) // 超出范围
                    {
                        vSpace = (int)(vOffset - vFileStream.Length);
                        vOffset = vFileStream.Length;
                    }
                    vFileStream.Seek(-vOffset, SeekOrigin.End); //“SeekOrigin.End”反方向偏移读取位置

                    vReadLength = vFileStream.Read(vBuffer, 0, vBuffer.Length - vSpace);
                    #region 所读的缓冲里有多少行
                    for (int i = vReadLength - 1; i >= 0; i--)
                    {
                        if (vBuffer[i] == 10)
                        {
                            if (vScanCount > 0) vLineCount++; // #13#10为回车换行
                            if (vLineCount >= ALineCount) break;
                        }
                        vScanCount++;
                    }
                    #endregion 所读的缓冲里有多少行
                } while (vReadLength >= vBuffer.Length && vOffset < vFileStream.Length &&
                    vLineCount < ALineCount);

                if (vReadCount > 1) // 读的次数超过一次，则需重分配缓冲区
                {
                    vBuffer = new byte[vScanCount];
                    vFileStream.Seek(-vScanCount, SeekOrigin.End);
                    vReadLength = vFileStream.Read(vBuffer, 0, vBuffer.Length);
                }
                return AEncoding.GetString(vBuffer, vReadLength - vScanCount, vScanCount);
            }
        }

        #endregion
    }
    public interface IDataPaser
    {
        List<string> getCorlumnNames();
        List<string> getLastRecord();
    }

}
